from django.db.models.query import Q
from django.forms.fields import Field, EMPTY_VALUES
from django.forms.util import ValidationError
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy as _
from pyparsing import ParseBaseException
from parser import QueryFilterParser


class QueryFilterField(Field):
    default_error_messages = {
        'invalid': _(u'Enter a valid filter. %s')
    }

    def __init__(self, parser_instance=None, *args, **kwargs):
        assert parser_instance
        self.parser = parser_instance
        super(QueryFilterField, self).__init__(*args, **kwargs)
        
    def clean(self, value):
        """
        Validates that the input can be converted to a Q object. Returns a
        Unicode object.
        """
        super(QueryFilterField, self).clean(value)
        if value in EMPTY_VALUES:
            value = u''
        value = smart_unicode(value)
        try:
            self.parser(value)
            # TODO: Perform a dry run of the filter on the destination model to spot lookup type errors
            # TODO: Make sure that the number of dry run^^^ results are >= from the minimum sample size
            return value
        except ParseBaseException, err:
            raise ValidationError(self.error_messages['invalid'] % err)
    
    def widget_attrs(self, widget):
        return {'rows': '2'}
